package com.bsoft.gol.hbs.dao;

import com.bsoft.gol.hbs.utils.CommonUtils;
import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.util.converter.ConversionUtils;
import hcn.base.Version;
import org.apache.commons.lang3.StringUtils;
import org.atag.dao.util.CustomAliasToEntityMapResultTransformer;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;
import pcn.bean.sign.VersionQo;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * VersionDao
 *
 * @author liq
 */

public abstract class VersionDAO extends HibernateSupportDelegateDAO<Version> {

    public VersionDAO() {
        this.setKeyField("id");
    }

    @DAOMethod(sql = "from Version where tenantPCode=:tenantPCode and version=(select max(version) from Version where tenantPCode=:tenantPCode)")
    public abstract Version getLatestVersion(@DAOParam("tenantPCode") String tenantPCode);

    @DAOMethod(sql = "from Version where tenantPCode=:tenantPCode and version=:version")
    public abstract Version getVersionByVersionId(@DAOParam("tenantPCode") String tenantPCode, @DAOParam("version") String version);

    @DAOMethod(sql = "from Version where tenantPCode=:tenantPCode")
    public abstract List<Version> findVersions(@DAOParam("tenantPCode") String tenantPCode);

    public Version getLatestVersionWithForceUpdate(final String tenantPCode, final String versionNumber) {
        HibernateStatelessResultAction<Version> action = new AbstractHibernateStatelessResultAction<Version>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder hsql = new StringBuilder();
                hsql.append("from Version where tenantPCode=:tenantPCode and version=(select max(version) from Version where tenantPCode=:tenantPCode)");
                Query sqlQuery = ss.createQuery(hsql.toString());
                sqlQuery.setParameter("tenantPCode", tenantPCode);

                List<Version> ls = sqlQuery.list();
                if (ls == null || ls.isEmpty()) {
                    setResult(null);
                    return;
                }
                Version version = ls.get(0);

                StringBuilder hsqlAll = new StringBuilder();
                hsqlAll.append("from Version where tenantPCode=:tenantPCode and version>:version");
                Query sqlQueryAll = ss.createQuery(hsqlAll.toString());
                sqlQueryAll.setParameter("tenantPCode", tenantPCode);
                sqlQueryAll.setParameter("version", versionNumber);
                List<Version> versions = sqlQueryAll.list();
                for (Version versionTemp : versions) {
                    if ("1".equals(versionTemp.getUpdateType())) {
                        version.setUpdateType("1");
                        break;
                    }
                }
                setResult(version);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     *获取最新版本信息 by liuxj
     * @param tenantPCode
     * @param versionNumber
     * @return
     */
    public Version getLatestVersionWithForceUpdateNew(final String tenantPCode, final String versionNumber) {
        HibernateStatelessResultAction<Version> action = new AbstractHibernateStatelessResultAction<Version>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder hsql = new StringBuilder();
                hsql.append(" select a.id,a.tenant_p_id,a.tenant_p_code,a.tenant_p_name,");
                hsql.append(" a.cloud_id,a.product_id,a.platform,a.version,a.url,b.update_type,a.content,a.memo,a.create_dt");
                hsql.append(" from base_version a");
                hsql.append(" inner join");
                hsql.append(" (");
                hsql.append("   select tenant_p_code,max(version) max_version,max(update_type) update_type from base_version");
                hsql.append("   where tenant_p_code = :tenantPCode and version > :version ");
                hsql.append("   group by tenant_p_code");
                hsql.append(" ) b on a.tenant_p_code = b.tenant_p_code and a.version = b.max_version");
                Query sqlQuery = ss.createSQLQuery(hsql.toString());
                sqlQuery.setParameter("tenantPCode",tenantPCode);
                sqlQuery.setParameter("version",versionNumber);
                sqlQuery.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String,Object>> dbList = sqlQuery.list();
                if (dbList == null || dbList.isEmpty()) {
                    setResult(null);
                    return;
                }
                List<Version> list = new ArrayList<Version>();
                for (Map<String,Object> data : dbList)
                {
                    list.add(ConversionUtils.convert(data,Version.class));
                }

                Version version = list.get(0);

                setResult(version);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 查询各个产品最新版本列表
     *
     * @param cloudId
     * @return
     */
    public List<Version> queryVersions(final String cloudId) {
        HibernateStatelessResultAction<List<Version>> action = new AbstractHibernateStatelessResultAction<List<Version>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder hsql = new StringBuilder();
                hsql.append("select a.*");
                hsql.append(" from base_version a");
                hsql.append(" inner join");
                hsql.append("(");
                hsql.append("   select tenant_p_id,platform,max(version) version");
                hsql.append("   from base_version");
                hsql.append("   group by tenant_p_id,platform");
                hsql.append(") b on a.tenant_p_id = b.tenant_p_id and a.version = b.version");
                if (cloudId != null && StringUtils.isNotEmpty(cloudId)) {
                    hsql.append(" where a.cloud_id = :cloudId");
                }

                SQLQuery sqlQuery = ss.createSQLQuery(hsql.toString());
                if (cloudId != null && StringUtils.isNotEmpty(cloudId)) {
                    sqlQuery.setParameter("cloudId", cloudId);
                }

                sqlQuery.setResultTransformer(CustomAliasToEntityMapResultTransformer.INSTANCE);
                List<Map> dbList = sqlQuery.list();
                List<Version> orgBeans = new ArrayList<>();
                for (Map map : dbList) {
                    orgBeans.add(ConversionUtils.convert(map, Version.class));
                }
                setResult(orgBeans);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 版本信息-查询单条
     *
     * @param id
     * @return
     */
    @DAOMethod(sql = " from Version where id =:id")
    public abstract Version getVersionById(@DAOParam("id") int id);

    /**
     * 版本信息-查询单条（新增判断）
     *
     * @param tenantPId
     * @param version
     * @return
     */
    @DAOMethod(sql = " from Version where tenantPId=:tenantPId and platform=:platform and version =:version")
    public abstract Version getVersionByTenantPIdAndVersion
    (@DAOParam("tenantPId") int tenantPId, @DAOParam("platform") String platform, @DAOParam("version") String version);

    /**
     * 版本信息-查询单条（修改判断）
     *
     * @param tenantPId
     * @param version
     * @return
     */
    @DAOMethod(sql = " from Version where tenantPId=:tenantPId and platform=:platform and version =:version and id<>:id")
    public abstract Version getVersionByTenantPIdAndVersionAndId
    (@DAOParam("tenantPId") int tenantPId, @DAOParam("platform") String platform,
     @DAOParam("version") String version, @DAOParam("id") int id);

    public List<Version> queryVersions(final VersionQo qo) {
        HibernateStatelessResultAction<List<Version>> action = new AbstractHibernateStatelessResultAction<List<Version>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuffer sql = new StringBuffer();
                sql.append("From Version");
                sql.append("  order by createDt desc  ");
                Query query = ss.createQuery(sql.toString());
                if (CommonUtils.isNotNull(qo.getPageNo()) && CommonUtils.isNotNull(qo.getPageSize())) {
                    int first = qo.getPageNo() > 0 ? (qo.getPageNo() - 1) * qo.getPageSize() : 0;
                    query.setFirstResult(first);
                    query.setMaxResults(qo.getPageSize());
                }
                //query = (SQLQuery) query.setResultTransformer(CustomAliasToEntityMapResultTransformer.INSTANCE);
//                List<Map> dbList = query.list();
                List<Version> versions = (List<Version>)query.list();
//                for (Map map : dbList) {
//                    versions.add(ConversionUtils.convert(map, Version.class));
//                }
                setResult(versions);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        List<Version> list = action.getResult();
        return list;
    }

    public BigInteger countVersions(final VersionQo qo) {
        HibernateStatelessResultAction<BigInteger> action = new AbstractHibernateStatelessResultAction<BigInteger>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuffer sql = new StringBuffer();
                sql.append("SELECT count(1) from base_version  ");
                SQLQuery query = ss.createSQLQuery(sql.toString());
                List list = query.list();
                if (list.size() == 1) {
                    Object o = list.get(0);
                    BigInteger count = (BigInteger) o;
                    setResult(count);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 版本信息-移动端查询
     *
     * @param tenantPCode
     * @param platform
     * @param cloudId
     * @return hcn.base.Version
     * @throws
     * @author tongtp
     * @date 2023/11/24 15:59
     */
    @DAOMethod(sql = " from Version where tenantPCode = :tenantPCode and platform = :platform and cloudId = :cloudId" +
            " and versionStatus  = '1'")
    public abstract List<Version> findVersionByTenantPCodeAndPlatform(@DAOParam("tenantPCode") String tenantPCode,
                                                                      @DAOParam("platform") String platform,
                                                                      @DAOParam("cloudId") String cloudId,
                                                                      @DAOParam(pageStart = true) int start,
                                                                      @DAOParam(pageLimit = true) int limit);

}
